$().ready(function () {
    // hide even though the element is in <noscript>
    $('.rating_nojs').hide();

    /*
     * mouse entering the 'stars' area -> user's rating is shown
     */
    var enterRating = function () {
        // had to unbind the entering here to prevent 'jitter' happening when the
        // pointer is close to the stars area edge
        $(this).unbind('mouseenter');

        // parse product ID
        var id = this.id.split("_")[1];

        // get user's own rating
        var userRatingText = $("#userrating_" + id).attr('title');

        // parse and show user's own rating when mouse in on top stars
        if (userRatingText !== '') {
            var userRating = parseFloat(userRatingText);
            if (!isNaN(userRating)) {
                var percentage = (userRating / 5) * 100 + "%";
                $(this).html($('<span/>').css('width', percentage));
            }
        }
    };


    /*
     * mouse leaves 'stars' area -> average is shown
     */
    var leaveRating = function () {
        // set average rating back
        var percentage = (parseFloat($(this).attr('title')) / 5) * 100 + '%';
        $(this).html($('<span/>').css('width', percentage));

        // enable handler for mouse entering
        $(this).mouseenter(enterRating);
    };


    /*
     * User clicks on a star, the rating is posted to the server, the rating is shown on the stars
     * and once the response comes with a new average, it is set 
     */
    var ratingClick = function (event) {
        // unbind mouse enter to prevent from showing user's previous ratings if the mouse is wiggled around
        $(this).unbind('mouseenter');

        // get id of product
        var id = this.id.split('_')[1];

        // calculate rating the user has selected
        var pos = event.pageX - $(this).offset().left;
        var rating = Math.floor(pos / ($(this).width() / 5)) + 1;
        var percentage = (rating * 20) + '%';

        // display user's selected new rating
        $(this).html($('<span/>').css('width', percentage));

        // save reference to the stars element where the click is happening
        var elem = $(this);

        // TODO how to dynamically get (reverse) ajax URL for /rate in template?
        var url = "/rate/" + id + "/" + rating;

        // unbind also mouse leave to prevent from immediately showing the old average when mouse leaves
        $(this).unbind('mouseleave');

        // do ajax call to post rating
        $.get(url, function (data) {
            //In the callback: update data (new average, count of votes, and user's rating) and rebind leave event

            var newAverage = data.rating;

            elem.attr('title', newAverage.toFixed(1));
            $('#userrating_' + id).attr('title', rating);
            $('#votes_' + id).html('(' + data.votes + ' vote' + (data.votes > 1 ? 's' : '') + ')');

            // bind the leaving action again to have the stars show the average if the mouse leaves
            elem.mouseleave(leaveRating);

            // invoke mouse leaving to have the new average shown (as the new average was received in this callback)
            elem.mouseleave();
        });
    };


    // enable handlers only if the user is authenticated
    if (USER_AUTHENTICATED) {
        $('.stars').mouseenter(enterRating);
        $('.stars').mouseleave(leaveRating);
        $('.stars').click(ratingClick);
        $('.stars').addClass('rateable');
    }

});

